package net.xdclass.shopproject.processor;

import net.xdclass.shopproject.service.ProductServiceImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * BeanPostProcessor
 *      是Spring IoC容器提供的一个扩展机制，用于拦截和修改新实例化的Bean对象的过程
 *      默认是对整个Spring容器中【所有的Bean】进行处理，如果对具体的某个bean处理，通过方法参数判断即可
 *      在容器实例化Bean对象后（执行构造函数），初始化方法执行【前后】的回调方法，提供Bean实例初始化期间加入自定义逻辑
 *
 *      初始化方法，指的是以下两种
 *          bean实现InitializingBean接口，对应的方法为afterPropertiesSet
 *          XML中定义bean的时候，有个属性叫做init-method指定初始化方法
 *
 *   注意
 *        BeanPostProcessor是在spring容器加载了bean的定义文件，且实例化bean之后执行
 *        BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后
 *
 *        BeanFactoryPostProcessor和BeanPostProcessor都是处理bean的生命周期中扩展点，使用场景不同
 *              BeanFactoryPostProcessor作用于bean实例化之前，读取配置元数据，且可以修改
 *              BeanPostProcessor作用于bean的实例化过程中，可以改变bean实例的值
 */
public class CustomBeanPostProcessor implements BeanPostProcessor {

    public CustomBeanPostProcessor() {
        System.out.println("CustomBeanPostProcessor-----------------构造函数执行");
    }

    /**
     * 初始化方法执行之前执行
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("CustomBeanPostProcessor-------------postProcessBeforeInitialization执行 调用beanName="+beanName);
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    /**
     * 初始化方法执行之后执行
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("CustomBeanPostProcessor-------------postProcessAfterInitialization 调用beanName="+beanName);
        if ("productService".equals(beanName)) {
            ProductServiceImpl productService = (ProductServiceImpl) bean;
            productService.setName("小滴课堂 v2");
            return BeanPostProcessor.super.postProcessAfterInitialization(productService, beanName);
        }
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}
